package org.zjx.action.game;

import org.zjx.analysis.window.NpcDialogueAnalysis;
import org.zjx.analysis.window.ShoppingAnalysis;
import org.zjx.action.basic.ScreenshotAction;
import org.zjx.action.game.gather.SyncPropAction;
import org.zjx.core.IWindow;
import org.zjx.model.prop.ItemTemplate;
import org.zjx.service.PropService;
import org.zjx.service.impl.PropServiceImpl;
import org.zjx.util.ImageUtil;

import java.awt.*;
import java.util.List;
import java.util.stream.Collectors;

public class ShoppingAction extends AbstractWindowAction {
    private final PropService propService = new PropServiceImpl();
    private ShoppingAnalysis shoppingAnalysis;

    private Rectangle itemArea;

    private final String itemName;
    private final int buyNumber;

    private void analysis() {
        shoppingAnalysis = new ShoppingAnalysis(targetWindow, stateManager.getGameState().getScreenshot());
    }

    public ShoppingAction(IWindow targetWindow, String itemName, int buyNumber) {
        super(targetWindow, false);
        this.itemName = itemName;
        this.buyNumber = buyNumber;
    }

    @Override
    public void open() {

    }

    @Override
    public void close() {
        analysis();
        if (!shoppingAnalysis.isOpened()) return;
        click(shoppingAnalysis.getCloseButtonPoint());
        delay(300);
        flush();
        close();
    }

    @Override
    public void reSetWindow() {
        if (shoppingAnalysis.isTransborder()) {
            drag(shoppingAnalysis.conversion(shoppingAnalysis.windowArea, shoppingAnalysis.getRefImageArea()), shoppingAnalysis.conversion(shoppingAnalysis.getOriginBounds(), shoppingAnalysis.getRefImageArea()));
            analysis();
        }
    }

    @Override
    public void mouseAloofWindow(Rectangle rect) {
        if (shoppingAnalysis.mouseInRect(rect)) {
            Point safePoint = shoppingAnalysis.findLargestRemainingAreaCenter(rect);
            move(safePoint);
            delay(300);
            new ScreenshotAction(targetWindow).execute();
            analysis();
        }
    }

    @Override
    protected void doExecute() throws Exception {
        analysis();
        reSetWindow();
        mouseAloofWindow(shoppingAnalysis.windowArea == null ? shoppingAnalysis.getOriginBounds() : shoppingAnalysis.windowArea);
        if (!shoppingAnalysis.isOpened()) return;
        updateItemArea();

        while (itemArea != null && shoppingAnalysis.getBuyCount() < buyNumber) {

            int off = buyNumber - shoppingAnalysis.getBuyCount();
            while (off-- > 0){
                click(itemArea);
                delay(30);
            }
            analysis();
            mouseAloofWindow(shoppingAnalysis.getOriginBounds());
        }
        delay(300);
        Rectangle buyButtonArea = shoppingAnalysis.conversion(shoppingAnalysis.windowArea,shoppingAnalysis.buyButtonArea());
        click(buyButtonArea);
        delay(500);
        new ScreenshotAction(targetWindow).execute();

        NpcDialogueAnalysis dialogueAnalysis = new NpcDialogueAnalysis(targetWindow, stateManager.getGameState().getScreenshot());
        while (dialogueAnalysis.isOpened()){
            click(dialogueAnalysis.getCloseButtonPoint());
            delay(200);
            new ScreenshotAction(targetWindow).execute();
            dialogueAnalysis = new NpcDialogueAnalysis(targetWindow, stateManager.getGameState().getScreenshot());
        }
        close();
        new SyncPropAction(targetWindow).execute();
    }

    private void updateItemArea() {
        List<String> imageStrings = convertImagesToStrings();
        List<ItemTemplate> itemTemplates = matchItemTemplates(imageStrings);
        for (int i = 0; i < itemTemplates.size(); i++) {
            ItemTemplate itemTemplate = itemTemplates.get(i);
            if (itemTemplate.getName().equals(itemName)) {
                itemArea = shoppingAnalysis.getItemIndexArea(i);
                return;
            }
        }
    }

    /**
     * 转换图片为字符串
     */
    private List<String> convertImagesToStrings() {
        return shoppingAnalysis.getItemImages().stream()
                .map(ImageUtil::bufferedImageToString)
                .collect(Collectors.toList());
    }

    /**
     * 匹配物品模板
     */
    private List<ItemTemplate> matchItemTemplates(List<String> imageStrings) {
        return propService.matcher(imageStrings);
    }
}
